﻿using AiQiuQuan.Sport.Core;
using AiQiuQuan.Sport.Model.Enums;
using AiQiuQuan.Sport.Model.Models;
using AiQiuQuan.Sport.WebApi.Entities;
using AiQiuQuan.Sport.WebApi.Repositories;
using System.Text.Json;

namespace AiQiuQuan.Sport.WebApi.Services.Impl
{
    /// <summary>
    /// 比赛积分规则
    /// </summary>
    public class GamePointRuleService : IGamePointRuleService
    {
        private readonly IGamePointRuleRepository _gamePointRuleRepository;
        private readonly JsonSerializerOptions _jsonOptions;

        /// <summary>
        /// ctor
        /// </summary>
        public GamePointRuleService(
            IGamePointRuleRepository gamePointRuleRepository)
        {
            _gamePointRuleRepository = gamePointRuleRepository;
            _jsonOptions = new JsonSerializerOptions { WriteIndented = false };
        }

        /// <summary>
        /// 初始化比赛积分规则
        /// </summary>
        public async Task<UnaryResult> InitAsync()
        {
            var list = new List<GamePointRule>();
            var teamCountArray = new int[] { 6, 8, 12, 16, 24, 32 };
            var tennisLevelList = new List<GameTennisLevelPointRuleDetail>
            {
                new GameTennisLevelPointRuleDetail{VersusType = GameVersusEnum.Single, Level = 2.5M, Times = 1},
                new GameTennisLevelPointRuleDetail{VersusType = GameVersusEnum.Single, Level = 3.5M, Times = 2},
                new GameTennisLevelPointRuleDetail{VersusType = GameVersusEnum.Single, Level = 4.5M, Times = 4},
                new GameTennisLevelPointRuleDetail{VersusType = GameVersusEnum.Single, Level = 5.5M, Times = 10},
                new GameTennisLevelPointRuleDetail{VersusType = GameVersusEnum.Single, Level = 0M, Times = 100},
                new GameTennisLevelPointRuleDetail{VersusType = GameVersusEnum.Double, Level = 5.0M, Times = 1},
                new GameTennisLevelPointRuleDetail{VersusType = GameVersusEnum.Double, Level = 7.0M, Times = 2},
                new GameTennisLevelPointRuleDetail{VersusType = GameVersusEnum.Double, Level = 9.0M, Times = 4},
                new GameTennisLevelPointRuleDetail{VersusType = GameVersusEnum.Double, Level = 11.0M, Times = 10},
                new GameTennisLevelPointRuleDetail{VersusType = GameVersusEnum.Double, Level = 0M, Times = 100},
            };
            var ageList = new List<GameAgePointRuleDetail>
            {
                new GameAgePointRuleDetail{Age = 8, Times = 1},
                new GameAgePointRuleDetail{Age = 10, Times = 2},
                new GameAgePointRuleDetail{Age = 13, Times = 4},
                new GameAgePointRuleDetail{Age = 15, Times = 10},
                new GameAgePointRuleDetail{Age = 18, Times = 100},
            };
            var teamList = new List<GameTeamPointRuleDetail>
            {
                new GameTeamPointRuleDetail{VersusType = GameVersusEnum.MaleSingle, Times = 1},
                new GameTeamPointRuleDetail{VersusType = GameVersusEnum.FemaleSingle, Times = 1},
                new GameTeamPointRuleDetail{VersusType = GameVersusEnum.MaleDouble, Times = 2},
                new GameTeamPointRuleDetail{VersusType = GameVersusEnum.FemaleDouble, Times = 2},
                new GameTeamPointRuleDetail{VersusType = GameVersusEnum.MixDouble, Times = 2},
            };
            foreach (var item in teamCountArray)
            {
                var rule1 = new GamePointRule
                {
                    GameType = GameTypeEnum.Level,
                    TeamCount = item,
                    TimesRule = JsonSerializer.Serialize(tennisLevelList, _jsonOptions)
                };
                SetPoint(rule1, item);
                var rule2 = new GamePointRule
                {
                    GameType = GameTypeEnum.Age,
                    TeamCount = item,
                    TimesRule = JsonSerializer.Serialize(ageList, _jsonOptions)
                };
                SetPoint(rule2, item);
                var rule3 = new GamePointRule
                {
                    GameType = GameTypeEnum.Team,
                    TeamCount = item,
                    TimesRule = JsonSerializer.Serialize(teamList, _jsonOptions)
                };
                SetPoint(rule3, item);

                list.Add(rule1);
                list.Add(rule2);
                list.Add(rule3);
            }

            await _gamePointRuleRepository.DeleteAsync(m => true);
            await _gamePointRuleRepository.BulkAddAsync(list);
            return UnaryResult.Succeed();
        }

        #region private methods
        /// <summary>
        /// 分排名积分设置
        /// </summary>
        private void SetPoint(GamePointRule rule, int teamCount)
        {
            switch (teamCount)
            {
                case 6:
                    rule.Rank1Point = 6;
                    rule.Rank2Point = 3;
                    rule.Rank3Point = 2;
                    rule.Rank4Point = 1;
                    break;
                case 8:
                    rule.Rank1Point = 8;
                    rule.Rank2Point = 4;
                    rule.Rank3Point = 2;
                    rule.Rank4Point = 1;
                    break;
                case 12:
                    rule.Rank1Point = 12;
                    rule.Rank2Point = 6;
                    rule.Rank3Point = 3;
                    rule.Rank4Point = 2;
                    rule.Rank8Point = 1;
                    break;
                case 16:
                    rule.Rank1Point = 16;
                    rule.Rank2Point = 8;
                    rule.Rank3Point = 4;
                    rule.Rank4Point = 2;
                    rule.Rank8Point = 1;
                    break;
                case 24:
                    rule.Rank1Point = 24;
                    rule.Rank2Point = 12;
                    rule.Rank3Point = 6;
                    rule.Rank4Point = 3;
                    rule.Rank8Point = 2;
                    rule.Rank16Point = 1;
                    break;
                case 32:
                    rule.Rank1Point = 32;
                    rule.Rank2Point = 16;
                    rule.Rank3Point = 8;
                    rule.Rank4Point = 4;
                    rule.Rank8Point = 2;
                    rule.Rank16Point = 1;
                    break;
            }
        }
        #endregion
    }
}
